<?php

namespace app\service\impl;

use app\enum\MessageConstant;
use app\enum\PasswordConstant;
use app\enum\StatusConstant;
use app\exception\AccountNotFoundException;
use app\popo\dto\EditPasswordRequest;
use app\popo\model\Employee;
use app\repository\EmployeeRepository;
use app\service\EmployeeService;
use app\support\JwtHelper;
use DI\Attribute\Inject;
use Illuminate\Support\Arr;



class EmployeeServiceImpl implements EmployeeService
{

    #[Inject]
    protected EmployeeRepository $employeeRepository;

    /**
     * @throws AccountNotFoundException
     */
    public function login(array $employeeLoginDTO)
    {
        $username = Arr::get($employeeLoginDTO, "username");
        $password = Arr::get($employeeLoginDTO, "password");

        $employee =  $this->employeeRepository->getByUsername($username);
        if (!$employee) {
            throw new AccountNotFoundException(MessageConstant::ACCOUNT_NOT_FOUND->value);
        }

         if (!password_verify($password, $employee->password)) {
             throw new AccountNotFoundException(MessageConstant::PASSWORD_ERROR->value);
         }

        if ($employee->status == StatusConstant::DISABLE->value) {
            throw new AccountNotFoundException(MessageConstant::ACCOUNT_LOCKED->value);
        }

        return $employee;
    }

    public function pageQuery(array $employeePageQueryDTO)
    {
        $pageResult = $this->employeeRepository->listOf($employeePageQueryDTO);
        return $pageResult->toArray();
    }

    public function save(array $employeeDTO): void
    {
        $employee = new Employee($employeeDTO);
        $employee->password = encrypt(PasswordConstant::DEFAULT_PASSWORD->value);
        $employee->saveByDto();
    }

    public function getById(int $id): Employee|null
    {
        return Employee::find($id);
    }

    public function startOrStop(int $status, int $id)
    {
        Employee::find($id)->updateWith(array("status" => $status));
    }

    public function update(array $employeeDTO)
    {
        $employee = $this->getById(Arr::get($employeeDTO, "id"));
        $employee->updateWith(Arr::except($employeeDTO, "id"));
    }

        /**
     * 修改员工密码
     * @param EditPasswordRequest $editPasswordRequest 密码数据传输对象
     * @return void
     */
    public function editPassword(EditPasswordRequest $editPasswordRequest): void
    {
        $employee = JwtHelper::getEmployee();

         if (!password_verify($editPasswordRequest->getOldPassword(), $employee->password)) {
             throw new AccountNotFoundException(MessageConstant::PASSWORD_ERROR->value);
         }
        $employee->update([
            'password' => encrypt($editPasswordRequest->getNewPassword())
        ]);
    }
}